<?php

/**
 * Controller
 *
 * Classe abstrada que sera a base de todas as controllers do Dracosys
 *
 * @author	Richard Brandao <richard@hostnet.com.br>
 * @since 	2011-02-24
 */

abstract class Controller implements IController, IControllerReturn {

    protected $View;

    private $tResponse;
    private $BoHasReturn = false;

    public function init() {
        Dracosys::unserializeSession();
        $this->View = new View();
    }

    public function validate() {
        $ArUrl = treatUrl();
        if( $ArUrl['Controller'] == 'login' ) { return true; }

        $ArControlAccessData = array(
            'StController' => $ArUrl['Controller'],
            'StAction' => $ArUrl['Action'],
            'StParam' => getParams()
        );
        $ControlAccess = new ControleAcao( $ArControlAccessData );

        if( $this->isFreePage($ControlAccess) ) {
            return true;
        }

        $ProfileLoggedUser = Dracosys::getLoggedUser()->getTPerfil();
        if( !$ProfileLoggedUser->isAbleToAccess( $ControlAccess ) ) {
            throw new PermissionDeniedException('Seu perfil não possui privilégios para acessar a URL: ' . $ArUrl['Controller'] . '/' . $ArUrl['Action']);
        }

        return true;
    }

    private function isFreePage($ControlAccess) {
        $ArFreePages = Dracosys::getSessionValue(SESSION_SYSTEM, 'FreeActions');
        foreach($ArFreePages as $Page) {
            if( $Page->allows($ControlAccess) ) {
                return true;
            }
        }
        return false;
    }

    public function permissionDenied( $StMessage ) {
        $this->save(SESSION_SYSTEM, 'PermissionMessage', $StMessage);
        redirect('index', 'permissao-negada');
    }

    public function commit() {
        $ArUrl = treatUrl();
        if( $ArUrl['Controller'] == 'login' && $ArUrl['Action'] == DEFAULT_ACTION_INDEX ) { return true; }
        Dracosys::cleanSessionValue(SESSION_INTERFACE);
        Dracosys::$tSession->commit();
    }

    public function addFeedback($StMessage) {
        $this->save(SESSION_INTERFACE, 'FEEDBACK', $StMessage);
    }

    /**
     *
     * @method  view
     *
     * Inclui uma view composta ou uma view simples.
     * View composta sao views com cabecalhos, footer, css, js e etc
     * View simples sao simplesmente os arquivos
     *
     * @param   string  $ViewFile   Nome da view a ser incluida
     * @param   string  $StPackage  Pacote onde se encontra a view
     * @param   boolean $SingleView Define se a view sera simples ou compsota
     *
     * @author  Richard Brandao <richardsbrando@gmail.com>
     * @since   2011-12-08
     */
    public function view($ViewFile, $StPackage, $SingleView = false) {
        if(!$SingleView) {
            $this->View->includeView($ViewFile, $StPackage);
        } else {
            $this->View->includeSingleFile($ViewFile, $StPackage);
        }
    }

    /**
     * @method  validateUser
     *
     * Valida usuário logado na sessao, caso a sessao tenha se expirado
     * retorna para a pagina de login
     *
     * @since   2011-12-12
     * @return  bool
     */
    public function validateUser() {
        if( getController() != 'login' && !Dracosys::isUsuario() ) {
            throw new UserNotLoggedException('Usuário não logado');
        }
        return true;
    }

    /**
     * @method  modelDao
     *
     * Chama a model de Persistencia (DAO)
     *
     * @param   string   $DaoClass  Noma da classe Dao a ser incluida
     *
     * @author  Richard Brandao <richardsbrandao@gmail.com>
     * @since   2011-12-06
     */
    public function modelDao($DaoClass) {
        require_once DRA_DAO_PATH . strtolower($DaoClass) . '.dao.php';
    }
    /**
     * @method  modelEntity
     *
     * Chama a model de Dominio (Entity)
     *
     * @param   string   $EntityClass  Noma da classe Entity a ser incluida
     *
     * @author  Richard Brandao <richardsbrandao@gmail.com>
     * @since   2011-12-06
     */
    public function modelEntity($EntityClass) {
        require_once DRA_ENTITY_PATH . strtolower($EntityClass) . '.entity.php';
    }
    /**
     * @method  modelService
     *
     * Chama a model de Servico (Service)
     *
     * @param   string   $ServiceClass  Noma da classe de Servico a ser incluida
     *
     * @author  Richard Brandao <richardsbrandao@gmail.com>
     * @since   2011-12-06
     */
    public function modelService($ServiceClass) {
        require_once DRA_SERVICE_PATH . strtolower($ServiceClass) . '.service.php';
    }
    /**
     * @method  save
     *
     * Salva em sessao valores salvos por uma respectiva controller que sera
     * usado nas views ou por outras controllers
     *
     * @param   string $StIndex   Indice que sera armazenado
     * @param   mixed  $MxValue   Valor a ser armazenado
     * @since   2011-09-10
     * @return  void
     */
    public function save($Base, $StIndex, $MxValue) {
        Dracosys::saveSessionValue($Base, $StIndex, $MxValue);
    }
    /**
     * @method  hasReturn
     *
     * Verifica se algum return foi salvo na requisicao
     *
     * @since   2011-09-06
     * @return  boolean
     */
    public function hasReturn() {
        return $this->BoHasReturn;
    }
    /**
     * @method  saveReturn
     *
     * Salva um objeto de retorno na resposta da requisicao.
     *
     * @since   2011-09-06
     * @author  Richard Brandao <richardsbrandao@gmail.com>
     * @return  boolean
     */
    public function saveReturn($StMessage, $ItType = 0, $StFile = __FILE__, $ItLine = false) {
        $this->BoHasReturn = true;
        $this->tResponse = new Retorno( $StMessage, $ItType, $StFile, $ItLine );
    }

    /**
     * @method  showJsonResponse
     *
     * Responde um objeto Json para view a partir de um objeto de retorno salvo
     * anteriormente
     *
     * @since   2011-09-06
     * @author  Richard Brandao <richardsbrandao@gmail.com>
     * @return  boolean
     */
    public function showJsonResponse() {
        echo json_encode($this->tResponse->parseArray());
    }

    protected function getTResponse() {
        return $this->tResponse;
    }

}

?>